﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Serialization;
using Arcanea.StateEditor.XmlObjects;
using System.IO;
using Arcanea.StateEditor.FormOption;
using System.Diagnostics;
using Arcanea.Mediator.XmlClasses;
using Arcanea.Mediator.Toolbox;

namespace Arcanea.StateEditor
{
    public partial class UserControlStateEditor : UserControl
    {
        //private IList<XmlPacket> AllXmlPackets = null;
        List<BulleTexte> allBulleText = new List<BulleTexte>();
        List<LinkRepresentation> allLinks = new List<LinkRepresentation>();
        private static XmlSerializer xmls = new XmlSerializer(typeof(AllObjects));

        public static string xmlFileNameState = "States.xml";
        public static string XMLFileNameState
        {
            get { return xmlFileNameState; }
            set { xmlFileNameState = value; }
        }

        public static string xmlFilePathState = Path.Combine(Application.StartupPath, xmlFileNameState);
        public static string XMLFilePathState
        {
            get { return xmlFilePathState; }
            set { xmlFilePathState = value; }
        }

        public static string xmlFilePathPacket = Path.Combine(Application.StartupPath, "Packets.xml");
        public static string XMLFilePathPacket
        {
            get { return xmlFilePathPacket; }
            set { xmlFilePathPacket = value; }
        }

        public UserControlStateEditor()
        {
            InitializeComponent();

        }

        private void buttonAdd_Click(object sender, EventArgs e)
        {
            BulleTexte bt = new BulleTexte();
            bt.GenerateGuid();
            this.Controls.Add(bt);
            allBulleText.Add(bt);
        }

        private void buttonDelete_Click(object sender, EventArgs e)
        {
            int i = 0;
            while (i < allBulleText.Count)
            {
                if (allBulleText[i].Selected)
                {
                    this.Controls.Remove(allBulleText[i]);
                    allBulleText.RemoveAt(i);
                }
                else
                {
                    i++;
                }
            }
            this.Refresh();
        }

        private void CheckLinks()
        {
            for (int i = 0; i < allLinks.Count; i++)
            {
                if (allLinks[i].Modele == null)
                {
                    this.Controls.Remove(allLinks[i]);
                    allLinks.Remove(allLinks[i]);
                    i--;
                }
            }
        }

        private void CheckBulleText()
        {
            for (int j = 0; j < allBulleText.Count; j++)
            {
                //l'utilisateur a supprimé la bulle texte
                if (allBulleText[j].Modele == null)
                {
                    this.Controls.Remove(allBulleText[j]);
                    allBulleText.Remove(allBulleText[j]);
                    j--;
                }
            }
        }

        private void MainFormServerEditor_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            Pen pnClient = new Pen(Color.Blue, 2);
            Pen pnServer = new Pen(Color.Red, 2);

            CheckLinks();
            CheckBulleText();

            float pourcent = 0.65f;

            for (int i = 0; i < allLinks.Count; i++)
            {
                bool parent1Found = false;
                bool parent2Found = false;
                for (int j = 0; j < allBulleText.Count; j++)
                {
                    Point locationStart = new Point(allBulleText[j].Location.X + allBulleText[j].ClientSize.Width / 2, allBulleText[j].Location.Y + allBulleText[j].ClientSize.Height);

                    if (allLinks[i].Modele.GUIDPere == allBulleText[j].Modele.GUID)
                    {
                        parent1Found = true;
                        foreach (BulleTexte btC in allBulleText)
                        {

                            if (allLinks[i].Modele.GUIDFils == btC.Modele.GUID)
                            {
                                parent2Found = true;
                                Pen pn = pnServer;
                                if (allLinks[i].Modele.IsClientDeclenche)
                                {
                                    pn = pnClient;
                                }
                                Point locationEnd = new Point(btC.Location.X + btC.ClientSize.Width / 2, btC.Location.Y);
                                g.DrawLine(pn, locationStart, locationEnd);
                                int LocationLinkX = (int)((float)locationStart.X * pourcent + (float)(locationEnd.X - 50) * (1 - pourcent));
                                int LocationLinkY = (int)((float)locationStart.Y * pourcent + (float)(locationEnd.Y - 50) * (1 - pourcent));
                                allLinks[i].Location = new Point(LocationLinkX, LocationLinkY);
                            }
                        }
                    }
                }

                if (!parent1Found || !parent2Found)
                {
                    allLinks[i].Modele = null;
                    this.Refresh();
                    return;
                }
            }
        }

        private void buttonLink_Click(object sender, EventArgs e)
        {
            

            BulleTexte b1 = null;
            BulleTexte b2 = null;
            int i = 0;
            while (i < allBulleText.Count)
            {
                if (allBulleText[i].Selected)
                {
                    if (b1 == null)
                    {
                        b1 = allBulleText[i];
                    }
                    else if (b2 == null)
                    {
                        b2 = allBulleText[i];
                    }
                    else
                    {
                        MessageBox.Show(this, "Please select 2 (and only 2) states");
                        return;
                    }
                }
                i++;
                this.Refresh();
            }

            if (b1 == null || b2 == null)
            {
                MessageBox.Show(this, "Please select at least 2 states");
                return;
            }

            FormOptionLinkRepresentation fm1 = new FormOptionLinkRepresentation(XMLFilePathPacket);

            LinkRepresentationXml lrX = fm1.Modele;

            lrX.NamePere = b1.Modele.Texte;
            lrX.NameFils = b2.Modele.Texte;
            fm1.Modele = lrX;

            DialogResult dr = fm1.ShowDialog();

            if (dr == DialogResult.OK)
            {
                LinkRepresentation lr = new LinkRepresentation(XMLFilePathPacket);
                lr.Modele = fm1.Modele;
                lr.GenerateGuid();

                if (fm1.Modele.NamePere == b1.Modele.Texte)
                {
                    lr.Modele.GUIDFils = b2.Modele.GUID;
                    lr.Modele.GUIDPere = b1.Modele.GUID;
                }
                else
                {
                    lr.Modele.GUIDFils = b1.Modele.GUID;
                    lr.Modele.GUIDPere = b2.Modele.GUID;
                }

                b1.Modele.GUIDLinks.Add(lr.Modele.GUID);
                b2.Modele.GUIDLinks.Add(lr.Modele.GUID);
                this.Controls.Add(lr);
                allLinks.Add(lr);
            }

            this.Refresh();
        }

        private void SaveXml()
        {
            AllObjects l = new AllObjects();
            int i = 0;
            while (i < allBulleText.Count)
            {
                l.allBulesText.Add(allBulleText[i].Modele);
                i++;
            }

            i = 0;
            while (i < allLinks.Count)
            {
                l.allLinks.Add(allLinks[i].Modele);
                i++;
            }

            XmlListPacketLoadingSaving(xmlFilePathState, l);
        }

        private void LoadXml()
        {
            int i = 0;
            while (i < allBulleText.Count)
            {
                allBulleText[i].Parent.Controls.Remove(allBulleText[i]);
            }

            AllObjects l = XmlListPacketLoadingLoading(xmlFilePathState);

            foreach (LinkRepresentationXml lr in l.allLinks)
            {
                LinkRepresentation lri = new LinkRepresentation(XMLFilePathPacket);
                lri.Modele = lr;
                this.Controls.Add(lri);
                allLinks.Add(lri);
            }

            foreach (BulleTexteXml b in l.allBulesText)
            {
                BulleTexte bt = new BulleTexte();
                bt.Modele = b;
                this.Controls.Add(bt);
                allBulleText.Add(bt);
            }


        }

        private static AllObjects XmlListPacketLoadingLoading(string filePath)
        {
            AllObjects allPacket = new AllObjects();
            if (!File.Exists(filePath))
            {
                return allPacket;
            }
            FileStream fs = null;
            try
            {
                fs = new FileStream(filePath, FileMode.Open);
                allPacket = (AllObjects)xmls.Deserialize(fs);

            }
            catch (Exception e)
            {
                MessageBox.Show("Impossible de charger le fichier de configuration : " + filePath + "(" + e.Message + ")");
            }
            finally
            {
                if (fs != null) fs.Close();
            }

            return allPacket;
        }

        private void XmlListPacketLoadingSaving(string filePath, AllObjects allPacket)
        {
            FileStream fs = null;
            try
            {
                fs = new FileStream(filePath, FileMode.Create);
                xmls.Serialize(fs, allPacket);
            }
            catch (Exception e)
            {
                MessageBox.Show("Impossible de sauvegarder le fichier de configuration : " + filePath + "(" + e.Message + ")");
            }
            finally
            {
                if (fs != null) fs.Close();
            }
        }

        private void timerSave_Tick(object sender, EventArgs e)
        {
            SaveXml();
            //AllXmlPackets = XMLToolbox.XmlListPacketLoading(XMLFilePathPacket);
            toolStripStatusLabelWhenSaved.Text = "Saved on " + DateTime.Now.ToString("T");
        }

        public void SaveState(object sender, FormClosingEventArgs e)
        {
            SaveXml();
        }

        private void UserControlMain_Load(object sender, EventArgs e)
        {
            if (Process.GetCurrentProcess().ProcessName != "devenv")
            {
                LoadXml();
                timerSave.Enabled = true;
                //AllXmlPackets = XMLToolbox.XmlListPacketLoading(XMLFilePathPacket);
            }
        }

        private void buttonExport_Click(object sender, EventArgs e)
        {
            FormOptionGenerate fog = new FormOptionGenerate();
            List<BulleTexteXml> allBulleTextXml = new List<BulleTexteXml>();
            List<LinkRepresentationXml> allLinksXml = new List<LinkRepresentationXml>();

            foreach (BulleTexte bt in allBulleText)
            {
                allBulleTextXml.Add(bt.Modele);
            }

            foreach (LinkRepresentation lr in allLinks)
            {
                allLinksXml.Add(lr.Modele);
            }

            fog.allBulles = allBulleTextXml;
            fog.allLinks = allLinksXml;
            fog.ShowDialog();
        }
    }
}
